<template>
  <div class="qs-table-container">
    <!-- 表格头部区域 -->
    <div v-if="$slots.header" class="qs-table-header">
      <slot name="header"></slot>
    </div>

    <!-- 表格主体 -->
    <el-table
      ref="tableRef"
      v-loading="loading"
      :border="border"
      :data="currentPageData"
      :header-row-class-name="headerRowClassName as any"
      :row-class-name="rowClassName as any"
      :row-key="rowKey"
      :size="size"
      :stripe="stripe"
      @row-click="handleRowClick"
      @selection-change="handleSelectionChange"
      @sort-change="handleSortChange"
    >
      <!-- 选择列 -->
      <el-table-column v-if="showSelection" align="center" type="selection" width="55" />

      <!-- 序号列 -->
      <el-table-column v-if="showIndex" align="center" label="序号" type="index" width="55" />

      <!-- 数据列 -->
      <template v-for="(column, index) in visibleColumns" :key="column.prop || index">
        <el-table-column
          :align="column.align || 'center'"
          :fixed="column.fixed"
          :label="column.label"
          :min-width="column.minWidth || 150"
          :prop="column.prop"
          show-overflow-tooltip
          :sortable="column.sortable"
          :width="column.width"
        >
          <template #default="scope">
            <!-- 使用命名插槽 -->
            <slot
              v-if="$slots[`column-${column.prop}`]"
              :column="column"
              :index="scope.$index"
              :name="`column-${column.prop}`"
              :row="scope.row"
            ></slot>

            <!-- 使用自定义组件 -->
            <template v-else-if="column.component">
              <component
                :is="resolveComponent(column.component)"
                v-model="scope.row[column.prop]"
                v-bind="getComponentProps(column, scope.row)"
                :row="scope.row"
                @update:model-value="(val) => handleCellValueUpdate(val, scope.row, column)"
              />
            </template>

            <!-- 默认文本渲染 -->
            <template v-else>
              {{ getCellValue(scope.row, column) }}
            </template>
          </template>
        </el-table-column>
      </template>

      <!-- 空数据显示 -->
      <template #empty>
        <slot name="empty">
          <el-empty description="暂无数据" />
        </slot>
      </template>
    </el-table>

    <!-- 分页组件 -->
    <div v-if="showPagination" class="qs-table-pagination">
      <slot name="pagination">
        <el-pagination
          background
          :current-page="pagination.currentPage"
          :layout="pagination.layout"
          :page-size="pagination.pageSize"
          :page-sizes="pagination.pageSizes"
          :total="pagination.total"
          @current-change="handlePageChange"
          @size-change="handleSizeChange"
        />
      </slot>
    </div>

    <!-- 错误信息显示 -->
    <div v-if="error" class="qs-table-error">
      <slot :error="error" name="error">
        <el-alert show-icon :title="error.message" type="error" />
      </slot>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { defineEmits, defineProps, resolveComponent, watch } from 'vue'
import { type TableColumn, useTable } from '../../hooks/useTable'

// 组件属性定义
const props = defineProps({
  // 数据相关
  data: {
    type: Array,
    default: () => [],
  },
  loading: {
    type: Boolean,
    default: false,
  },

  // 列配置
  columns: {
    type: Array,
    default: () => [],
  },

  // 分页相关
  page: {
    type: Number,
    default: 1,
  },
  pageSize: {
    type: Number,
    default: 10,
  },
  total: {
    type: Number,
    default: 0,
  },
  pageSizes: {
    type: Array as () => number[],
    default: () => [10, 20, 50, 100],
  },
  layout: {
    type: String,
    default: 'total, sizes, prev, pager, next, jumper',
  },

  // 选择相关
  showSelection: {
    type: Boolean,
    default: false,
  },
  selectedRowKeys: {
    type: Array as () => string[],
    default: () => [],
  },

  // 序号列
  showIndex: {
    type: Boolean,
    default: true,
  },

  // 操作列
  showOperation: {
    type: Boolean,
    default: true,
  },
  operationLabel: {
    type: String,
    default: '操作',
  },
  operationWidth: {
    type: [String, Number],
    default: 150,
  },

  // 表格样式
  border: {
    type: Boolean,
    default: true,
  },
  stripe: {
    type: Boolean,
    default: true,
  },
  size: {
    type: String as () => 'default' | 'small' | 'large',
    default: 'default',
  },

  // 行相关
  rowKey: {
    type: String,
    default: 'id',
  },
  rowClassName: {
    type: [String, Function],
    default: '',
  },
  headerRowClassName: {
    type: [String, Function],
    default: '',
  },

  // 分页控制
  showPagination: {
    type: Boolean,
    default: true,
  },

  // 远程加载
  remote: {
    type: Boolean,
    default: false,
  },
})

// 组件事件
const emit = defineEmits([
  'update:page',
  'update:pageSize',
  'update:selectedRowKeys',
  'selection-change',
  'page-change',
  'size-change',
  'sort-change',
  'row-click',
  'update-query',
  'reload',
])

// 使用表格Hook
const {
  data,
  loading,
  error,
  pagination,
  visibleColumns,
  currentPageData,
  tableRef,
  setData,
  setPage,
  setPageSize,
  setTotal,
  handlePageChange: hookHandlePageChange,
  handleSizeChange: hookHandleSizeChange,
  handleSortChange: hookHandleSortChange,
  handleSelectionChange: hookHandleSelectionChange,
  getCellValue,
  getComponentProps,
  handleCellValueUpdate,
} = useTable({
  data: props.data,
  loading: props.loading,
  page: props.page,
  pageSize: props.pageSize,
  total: props.total,
  pageSizes: props.pageSizes,
  layout: props.layout,
  columns: props.columns as TableColumn[],
  selectedRowKeys: props.selectedRowKeys,
  rowKey: props.rowKey,
  remote: props.remote,
})

// 监听属性变化
watch(
  () => props.data,
  (newData) => {
    setData(newData)
  }
)

watch(
  () => props.page,
  (newPage) => {
    setPage(newPage)
  }
)

watch(
  () => props.pageSize,
  (newPageSize) => {
    setPageSize(newPageSize)
  }
)

watch(
  () => props.total,
  (newTotal) => {
    setTotal(newTotal)
  }
)

watch(
  () => props.columns,
  () => {
    // 这里不直接设置列，而是通过setData触发组件重新渲染
    setData([...data.value])
  }
)

// 处理页码变化
const handlePageChange = (page: number) => {
  // 直接更新页码并发出事件
  emit('update:page', page)
  emit('page-change', page)

  // 如果需要远程数据，才发出查询更新事件
  if (props.remote) {
    const query = hookHandlePageChange(page)
    emit('update-query', query)
  }
}

// 处理每页条数变化
const handleSizeChange = (pageSize: number) => {
  // 直接更新页大小并发出事件
  emit('update:pageSize', pageSize)
  emit('size-change', pageSize)

  // 如果需要远程数据，才发出查询更新事件
  if (props.remote) {
    const query = hookHandleSizeChange(pageSize)
    emit('update-query', query)
  }
}

// 处理排序变化
const handleSortChange = (params: { prop: string; order: 'ascending' | 'descending' | null }) => {
  const query = hookHandleSortChange(params)
  emit('sort-change', params)
  emit('update-query', query)
}

// 处理选择变化
const handleSelectionChange = (selection: any[]) => {
  hookHandleSelectionChange(selection)
  emit(
    'update:selectedRowKeys',
    selection.map((row) => row[props.rowKey])
  )
  emit('selection-change', selection)
}

// 处理行点击
const handleRowClick = (row: any, column: any, event: Event) => {
  emit('row-click', row, column, event)
}

// 组件方法暴露
defineExpose({
  // 暴露引用
  tableRef,

  // 暴露数据
  tableData: data,

  // 暴露方法
  reload: () => {
    const query = hookHandleSizeChange(pagination.value.pageSize)
    emit('reload', query)
    return query
  },
  clearSelection: () => {
    if (tableRef.value) {
      tableRef.value.clearSelection()
    }
  },
  toggleRowSelection: (row: any, selected?: boolean) => {
    if (tableRef.value) {
      tableRef.value.toggleRowSelection(row, selected)
    }
  },
  toggleAllSelection: () => {
    if (tableRef.value) {
      tableRef.value.toggleAllSelection()
    }
  },
})
</script>

<style scoped>
.qs-table-container {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
}

.qs-table-header {
  margin-bottom: 16px;
}

.qs-table-pagination {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
}

.qs-table-error {
  margin-top: 16px;
}

/* 自定义单元格状态样式 */
:deep(.cell-success) {
  color: #67c23a;
}

:deep(.cell-warning) {
  color: #e6a23c;
}

:deep(.cell-danger) {
  color: #f56c6c;
}

:deep(.cell-info) {
  color: #909399;
}

.table-operation-column {
  display: flex;
  justify-content: center;
  gap: 8px;
  white-space: nowrap;
}
</style>
